/*** 工具函数开始 ***/
// 随机生成范围内的数字
function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min) + min);
}
// 监听并捕获键盘事件的方法
function keyboard(value) {
  let key = {};
  key.value = value;
  key.isDown = false;
  key.isUp = true;
  key.press = undefined;
  key.release = undefined;
  //The `downHandler`
  key.downHandler = (event) => {
    if (event.key === key.value) {
      if (key.isUp && key.press) key.press();
      key.isDown = true;
      key.isUp = false;
      event.preventDefault();
    }
  };

  //The `upHandler`
  key.upHandler = (event) => {
    if (event.key === key.value) {
      if (key.isDown && key.release) key.release();
      key.isDown = false;
      key.isUp = true;
      event.preventDefault();
    }
  };

  //Attach event listeners
  const downListener = key.downHandler.bind(key);
  const upListener = key.upHandler.bind(key);

  window.addEventListener("keydown", downListener, false);
  window.addEventListener("keyup", upListener, false);

  // Detach event listeners
  key.unsubscribe = () => {
    window.removeEventListener("keydown", downListener);
    window.removeEventListener("keyup", upListener);
  };

  return key;
}
/*** 工具函数结束 ***/

// 搭建舞台
const app = new PIXI.Application({
  // 舞台宽高
  width: 750,
  height: 1440,
  // 设置游戏背景
  backgroundColor: 0xffbd3e,
});
// 将舞台插入到页面
$("#app").append(app.view);

// 资源加载
app.loader
  .add([
    { name: "zkkl", url: "./fonts/zkkl.ttf" },
    // {name:'p1_01',url:'./images/p1_01.png'},
    // {name:'p1_02',url:'./images/p1_02.png'},
    // {name:'p1_03',url:'./images/p1_03.png'},
    // {name:'p1_04',url:'./images/p1_04.png'},
    { name: "p2_01", url: "./images/p2_01.png" },
    { name: "p2_02", url: "./images/p2_02.png" },
    { name: "p2_03", url: "./images/p2_03.png" },
    { name: "p3_01", url: "./images/p3_01.png" },
    { name: "p3_02", url: "./images/p3_02.png" },
    { name: "p3_03", url: "./images/p3_03.png" },
    { name: "p3_04", url: "./images/p3_04.png" },
    { name: "p3_black_car", url: "./images/p3_black_car.png" },
    { name: "p3_red_car", url: "./images/p3_red_car.png" },
    { name: "p3_white_car", url: "./images/p3_white_car.png" },
    { name: "p3_yellow_car", url: "./images/p3_yellow_car.png" },
    { name: "p4_01", url: "./images/p4_01.png" },
    { name: "p4_02", url: "./images/p4_02.png" },
    { name: "p4_03", url: "./images/p4_03.png" },
    { name: "p4_04", url: "./images/p4_04.png" },
    { name: "p4_barrier_1", url: "./images/p4_barrier_1.png" },
    { name: "p4_barrier_2", url: "./images/p4_barrier_2.png" },
    { name: "p4_barrier_3", url: "./images/p4_barrier_3.png" },
    { name: "p4_barrier_4", url: "./images/p4_barrier_4.png" },
    { name: "p4_black_car", url: "./images/p4_black_car.png" },
    { name: "p4_red_car", url: "./images/p4_red_car.png" },
    { name: "p4_white_car", url: "./images/p4_white_car.png" },
    { name: "p4_yellow_car", url: "./images/p4_yellow_car.png" },
    { name: "p4_lane", url: "./images/p4_lane.png" },
    { name: "p4_left_btn", url: "./images/p4_left_btn.png" },
    { name: "p4_right_btn", url: "./images/p4_right_btn.png" },
    { name: "p5_01", url: "./images/p5_01.png" },
    { name: "p5_02", url: "./images/p5_02.png" },
    { name: "p5_03", url: "./images/p5_03.png" },
    { name: "p5_black_car", url: "./images/p5_black_car.png" },
    { name: "p5_red_car", url: "./images/p5_red_car.png" },
    { name: "p5_white_car", url: "./images/p5_white_car.png" },
    { name: "p5_yellow_car", url: "./images/p5_yellow_car.png" },
  ])
  .load(setup)
  .on("progress", (loader, res) => {
    // 拿到进度条百分比
    let progress = parseInt(loader.progress);

    // 加载完成时显示开始游戏按钮
    if (progress >= 99) {
      // 将进度条最大值固定为100
      progress = 100;
      // 显示开始按钮
      p1_02.visible = true;
    }
    // 更新加载状态描述
    p1_load_text.text = `游戏加载进度${progress}%`;
  });

// 碰撞函数
let bump = new Bump(PIXI);

let global = {
  winWidth: $(window).width(), // 屏幕宽
  winHeight: $(window).height(), // 屏幕高
  gamePlay: false, // 控制游戏，开启【true】还是关闭【false】
  gameLaneSpeed: 5, // 赛道速度
  gameBarrieMaxSpeed: 10, // 障碍物最快速度
  gameScoreBonus: 10, // 与金币碰撞后的用户加分
  gameCountdown: 3, // 倒计时开始数字
  gameActiveColorCar: 1, // 1：黄色汽车, 2：白色汽车, 3：红色汽车, 4：黑色汽车
  gameResScore: 0, // 用户最终得分
  gamePlusSpeed: 0.2, // 每秒增加的游戏速度
};

/**** p1页 start ****/
// 创建第一页分组容器
let p1 = new PIXI.Container();
// 设置容器宽高
p1.width = 750;
p1.height = 1160;
// 设置容器位置
p1.position.set(0, (app.view.height - p1._height) / 2);

// 创建'标题'精灵
let p1_01 = new PIXI.Sprite.from("./images/p1_01.png");
// 设置'标题'精灵位置
p1_01.position.set((p1._width - 473) / 2, 0);

// 创建文本精灵并设置默认值
let p1_load_text = new PIXI.Text("游戏加载进度0%", {
  fontFamily: "zkkl",
  fontSize: 36,
  fill: 0xffffff,
});
// 设置loading文本精灵位置
p1_load_text.position.set((app.view.width - p1_load_text.width) / 2, 168);

// 创建'开始按钮'精灵
let p1_02 = new PIXI.Sprite.from("./images/p1_02.png");
// 启用'开始按钮'精灵的交互响应
p1_02.interactive = true;
// 设置'开始按钮'精灵的位置
p1_02.position.set((app.view.width - 244) / 2, p1._height - 100);
// 隐藏'开始按钮'精灵
p1_02.visible = false;
// 给'开始按钮'精灵绑定触摸事件
p1_02.on("tap", (ev) => {
  // 隐藏'第一页'分组容器
  p1.visible = false;
  // 显示'第二页'容器
  p2.visible = true;
});

// 创建'赛道图'精灵
let p1_03 = new PIXI.Sprite.from("./images/p1_03.png");
// 设置'赛道图'精灵位置
p1_03.position.set(0, 220);

// 创建'赛道汽车图'精灵
let p1_04 = new PIXI.Sprite.from("./images/p1_04.png");
// 设置'赛道汽车图'精灵
p1_04.position.set(0, 450);

// 将'标题'、'开始按钮'、'赛道图'、'赛道汽车图'、'赛道汽车图'、'loading文本'
p1.addChild(p1_01, p1_02, p1_03, p1_04, p1_load_text);
// 将'第一页'容器添加到舞台
app.stage.addChild(p1);
/**** p1页 end ****/

// 逻辑执行函数
let p2 = null;
// 在图像资源加载完成后触发
function setup(loader, res) {
  /**** p2页 start ****/
  // 创建'第二页'容器
  p2 = new PIXI.Container();
  // 隐藏'第二页'容器
  p2.visible = false;
  // 设置'第二页'容器宽高
  p2.width = 750;
  p2.height = 1160;
  // 设置'第二页'容器位置
  p2.position.set(0, (app.view.height - p2._height) / 2);

  // 创建'规则标题'精灵
  let p2_01 = new PIXI.Sprite.from(res.p2_01.texture);
  // 设置'规则标题'精灵位置
  p2_01.position.set((app.view.width - p2_01.width) / 2, 30);

  // 创建'规则内容'精灵
  let p2_02 = new PIXI.Sprite.from(res.p2_02.texture);
  // 设置'规则内容'精灵
  p2_02.position.set((app.view.width - p2_02.width) / 2, 120);

  // 创建'规则确认按钮'精灵
  let p2_03 = new PIXI.Sprite.from(res.p2_03.texture);
  // 启用'规则确认按钮'精灵的交互响应
  p2_03.interactive = true;
  // 设置'规则确认按钮'精灵的位置
  p2_03.position.set((app.view.width - p2_03.width) / 2, p2._height - 100);
  // 给'规则确认按钮'精灵绑定触摸事件
  p2_03.on("tap", () => {
    // 隐藏'第二页'容器
    p2.visible = false;
    // 显示'第三页'容器
    p3.visible = true;
  });

  // 将'规则标题'、'规则内容'、'规则确认按钮'等精灵添加'第二页'容器中
  p2.addChild(p2_01, p2_02, p2_03);
  // 将'第二页'容器添加到舞台中
  app.stage.addChild(p2);
  /**** p2页 end ****/

  /**** p3页 start ****/
  // 创建'第三页'容器
  let p3 = new PIXI.Container();
  // 隐藏'第三页'容器
  p3.visible = false;
  // 设置'第三页'容器宽高
  p3.width = 750;
  p3.height = 1160;
  // 设置'第三页'容器位置
  p3.position.set(0, (app.view.height - p3._height) / 2);

  // 创建'第三页标题'精灵
  let p3_01 = new PIXI.Sprite.from(res.p3_01.texture);
  // 设置'第三页标题'精灵位置
  p3_01.position.set((app.view.width - p3_01.width) / 2, 40);

  // 创建'汽车组'容器
  let p3_car_group = new PIXI.Container();
  // 设置'汽车组'容器宽高
  p3_car_group.width = p3_car_group.height = 750;
  // 设置'汽车组'容器位置
  p3_car_group.position.set(0, (p3._height - p3_car_group._height) / 2);

  // 创建'激活汽车标志'精灵
  let p3_02 = new PIXI.Sprite.from(res.p3_02.texture);
  // 设置'激活汽车标志'精灵移动范围
  let p302PositionArr = [
    { x: 210, y: 20 },
    { x: 495, y: 20 },
    { x: 210, y: 380 },
    { x: 495, y: 380 },
  ];
  // 设置'激活汽车标志'精灵位置
  p3_02.position.set(p302PositionArr[0].x, p302PositionArr[0].y);

  // 设置汽车移动范围
  let p3CarPositionArr = [
    { x: 155, y: 82 },
    { x: 440, y: 82 },
    { x: 155, y: 440 },
    { x: 440, y: 440 },
  ];
  // 创建'黄色汽车'精灵
  let p3_yellow_car = new PIXI.Sprite.from(res.p3_yellow_car.texture);
  // 设置'黄色汽车'精灵的位置
  p3_yellow_car.position.set(p3CarPositionArr[0].x, p3CarPositionArr[0].y);
  // 启用'黄色汽车'精灵的交互响应
  p3_yellow_car.interactive = true;
  // 给'黄色汽车'精灵绑定触摸事件
  p3_yellow_car.on("tap", () => {
    // 更新'激活汽车标志'精灵位置
    p3_02.position.set(p302PositionArr[0].x, p302PositionArr[0].y);
    // 更新激活汽车索引
    global.gameActiveColorCar = 1;
  });

  // 创建'白色汽车'精灵
  let p3_white_car = new PIXI.Sprite.from(res.p3_white_car.texture);
  // 设置'白色汽车'精灵的位置
  p3_white_car.position.set(p3CarPositionArr[1].x, p3CarPositionArr[1].y);
  // 启用'白色汽车'精灵的交互响应
  p3_white_car.interactive = true;
  // 给'白色汽车'精灵绑定触摸事件
  p3_white_car.on("tap", () => {
    // 更新'激活汽车标志'精灵位置
    p3_02.position.set(p302PositionArr[1].x, p302PositionArr[1].y);
    // 更新激活汽车索引
    global.gameActiveColorCar = 2;
  });

  // 创建'红色汽车'精灵
  let p3_red_car = new PIXI.Sprite.from(res.p3_red_car.texture);
  // 设置'红色汽车'精灵的位置
  p3_red_car.position.set(p3CarPositionArr[2].x, p3CarPositionArr[2].y);
  // 启用'红色汽车'精灵的交互响应
  p3_red_car.interactive = true;
  // 给'红色汽车'精灵绑定触摸事件
  p3_red_car.on("tap", () => {
    // 更新'激活汽车标志'精灵位置
    p3_02.position.set(p302PositionArr[2].x, p302PositionArr[2].y);
    // 更新激活汽车索引
    global.gameActiveColorCar = 3;
  });

  // 创建'黑色汽车'精灵
  let p3_black_car = new PIXI.Sprite.from(res.p3_black_car.texture);
  // 设置'黑色汽车'精灵的位置
  p3_black_car.position.set(p3CarPositionArr[3].x, p3CarPositionArr[3].y);
  // 启用'黑色汽车'精灵的交互响应
  p3_black_car.interactive = true;
  // 给'黑色汽车'精灵绑定触摸事件
  p3_black_car.on("tap", () => {
    // 更新'激活汽车标志'精灵位置
    p3_02.position.set(p302PositionArr[3].x, p302PositionArr[3].y);
    // 更新激活汽车索引
    global.gameActiveColorCar = 4;
  });

  // 将四种汽车以及汽车标志添加到'汽车组'容器中
  p3_car_group.addChild(
    p3_yellow_car,
    p3_white_car,
    p3_red_car,
    p3_black_car,
    p3_02
  );

  // 创建'确定汽车按钮'精灵
  let p3_04 = new PIXI.Sprite.from(res.p3_04.texture);
  // 启用'确定汽车按钮'精灵交互响应
  p3_04.interactive = true;
  // 设置'确定汽车按钮'精灵的位置
  p3_04.position.set((app.view.width - p3_04.width) / 2, p3._height - 100);

  let _randomLane = 0; // 随机车道
  // 敌人移动速度
  let _plusSpeed = 0; // 根据时间段增加速度，增加游戏难度
  // 让敌人移动的定时器
  let _timer2 = null;
  // 开始游戏的方法
  const gameStart = function () {
    // 隐藏'第三页'容器
    p3.visible = false;
    // 显示'第四页'(游戏主界面)容器
    p4.visible = true;
    // 数据重置(初始化敌人移动速度)
    _plusSpeed = 0;
    // 设置四个赛道中的障碍物随机速度
    barrieRdArr = {
      rd1: randomInt(global.gameLaneSpeed, global.gameBarrieMaxSpeed),
      rd2: randomInt(global.gameLaneSpeed, global.gameBarrieMaxSpeed),
      rd3: randomInt(global.gameLaneSpeed, global.gameBarrieMaxSpeed),
      rd4: randomInt(global.gameLaneSpeed, global.gameBarrieMaxSpeed),
    };
    // 总分重置
    p4TotalScoreText2.text = global.gameResScore = 0;
    // 障碍物重置(在页面清空)
    trackBarrie["barrier1"].y =
      trackBarrie["barrier2"].y =
      trackBarrie["barrier3"].y =
      trackBarrie["barrier4"].y =
        -150;
    // 赛道重置
    p4_lane1.position.y = 0;
    p4_lane2.position.y = -p4_lane1.height;

    // 显示'倒计时'精灵
    p4CountdownGroup.visible = true;
    // 圆圈图标显示
    p4_04.rotation = 0;
    p4_04.pivot.set(154, 154);

    let cdTime = global.gameCountdown;
    //重置倒计时数字位置
    p4CountdownText.text = cdTime;
    p4CountdownText.position.set(
      (p4_04.width - p4CountdownText.width) / 2,
      (p4_04.height - p4CountdownText.height) / 2
    );
    clearInterval(timer1);
    clearInterval(_timer2);
    // 创建'游戏主界面'开始倒计时的定时器
    var timer1 = setInterval(() => {
      if (cdTime > 0) {
        cdTime -= 1;
        p4CountdownText.text = cdTime == 0 ? "Go" : cdTime;
        p4CountdownText.position.set(
          (p4_04.width - p4CountdownText.width) / 2,
          (p4_04.height - p4CountdownText.height) / 2
        );
      } else {
        //关闭倒计时
        p4CountdownGroup.visible = false;
        //游戏开关打开
        global.gamePlay = true;
        clearInterval(timer1);
        // 游戏速度(敌人速度)
        _timer2 = setInterval(() => {
          _plusSpeed += global.gamePlusSpeed;
        }, 1000);
      }
    }, 1000);

    // 显示'激活汽车'
    trackCar[`car${global.gameActiveColorCar}`].visible = true;
    // 拿到汽车的随机位置(使汽车走到随机的车道上，但不会走到应急车道中)
    _randomLane = randomInt(1, 5);
    // 设置汽车位置
    trackCar[`car${global.gameActiveColorCar}`].x =
      p4CarInTrackArr[_randomLane].x;
  };

  // 给'确定汽车按钮'精灵绑定触摸事件
  p3_04.on("tap", () => {
    // 调用游戏开始方法
    gameStart();
  });

  // 将'第三页标题'、'汽车组容器'、'确定汽车按钮'等精灵添加到'第三页'容器中
  p3.addChild(p3_01, p3_car_group, p3_04);
  // 将'第三页'容器添加到舞台中
  app.stage.addChild(p3);
  /**** p3页 end ****/

  /**** p4页 start ****/
  // 创建'第四页'容器
  let p4 = new PIXI.Container();
  // 隐藏'第四页'容器
  p4.visible = false;
  // 设置'第四页'容器宽高
  p4.width = 750;
  p4.height = global.winHeight;
  // 创建'顶部状态栏'容器
  let p4TopGroup = new PIXI.Container();
  // 设置'顶部状态栏'容器宽高
  p4TopGroup.width = 750;
  p4TopGroup.height = 100;

  // 创建'顶部状态栏背景'精灵
  let p4_01 = new PIXI.Sprite.from(res.p4_01.texture);

  // 创建'用户总得分'文本
  let p4TotalScoreText1 = new PIXI.Text("总得分: ", {
    fontFamily: "zkkl",
    fontSize: 30,
  });
  // 设置'用户总得分'文本位置
  p4TotalScoreText1.position.set(275, 33);
  // 创建'得分'文本
  let p4TotalScoreText2 = new PIXI.Text("0", {
    fontFamily: "zkkl",
    fontSize: 30,
  });
  // 设置'得分'文本位置
  p4TotalScoreText2.position.set(275 + p4TotalScoreText1.width, 33);

  // 创建'游戏场景'(赛道、障碍物及汽车)容器
  let p4LaneGroup = new PIXI.Container();
  // 设置'游戏场景'(赛道、障碍物及汽车)容器的位置
  p4LaneGroup.position.set(0, 100);
  // 创建'赛道'精灵
  let p4_lane1 = new PIXI.Sprite.from(res.p4_lane.texture);
  // 设置'赛道'精灵位置
  p4_lane1.position.set(0, 0);
  // 创建'赛道'精灵
  let p4_lane2 = new PIXI.Sprite.from(res.p4_lane.texture);
  // 设置'赛道精灵位置'(在主赛道上面,边界之外)
  p4_lane2.position.set(0, -p4_lane1.height);

  // 障碍物在赛道中的位置数组
  let p4BarrieInTrackArr = [
    { x: 150, y: -150 }, // 第一条道
    { x: 275, y: -150 }, // 第二条道
    { x: 400, y: -150 }, // 第三条道
    { x: 525, y: -150 }, // 第四条道
  ];
  // 赛道中的障碍物（包括金币）
  let trackBarrie = {};
  // 创建'黄色路障桩'精灵
  trackBarrie["barrier1"] = new PIXI.Sprite(res.p4_barrier_1.texture);
  // 设置'黄色路障桩'精灵位置
  trackBarrie["barrier1"].position.set(150, -150);
  // 创建'蓝色路障桩'精灵
  trackBarrie["barrier2"] = new PIXI.Sprite(res.p4_barrier_2.texture);
  // 设置'蓝色路障桩'精灵位置
  trackBarrie["barrier2"].position.set(275, -150);
  // 创建'红色路障桩'精灵
  trackBarrie["barrier3"] = new PIXI.Sprite(res.p4_barrier_3.texture);
  // 设置'红色路障桩'精灵位置
  trackBarrie["barrier3"].position.set(400, -150);
  // 创建'奖励金币'精灵
  trackBarrie["barrier4"] = new PIXI.Sprite(res.p4_barrier_4.texture);
  // 设置'奖励金币'精灵位置
  trackBarrie["barrier4"].position.set(525, -150);

  // 汽车在赛道中的位置数组
  let p4CarInTrackArr = [
    { x: 15, y: 980 }, // 应急车道左道
    { x: 140, y: 980 }, // 第一条道
    { x: 270, y: 980 }, // 第二条道
    { x: 400, y: 980 }, // 第三条道
    { x: 520, y: 980 }, // 第四条道
    { x: 645, y: 980 }, // 应急车道右道
  ];
  // 赛道中的汽车
  let trackCar = {};
  // 创建'黄色赛道汽车'精灵
  trackCar["car1"] = new PIXI.Sprite(res.p4_yellow_car.texture);
  // 隐藏'黄色赛道汽车'精灵
  trackCar["car1"].visible = false;
  // 设置'黄色赛道汽车'精灵位置
  trackCar["car1"].position.set(520, 980);

  // 创建'白色赛道汽车'精灵
  trackCar["car2"] = new PIXI.Sprite(res.p4_white_car.texture);
  // 隐藏'白色赛道汽车'精灵
  trackCar["car2"].visible = false;
  // 设置'白色赛道汽车'精灵位置
  trackCar["car2"].position.set(400, 980);

  // 创建'红色赛道汽车'精灵
  trackCar["car3"] = new PIXI.Sprite(res.p4_red_car.texture);
  // 隐藏'红色赛道汽车'精灵
  trackCar["car3"].visible = false;
  // 设置'红色赛道汽车'精灵位置
  trackCar["car3"].position.set(275, 980);

  // 创建'红色赛道汽车'精灵
  trackCar["car4"] = new PIXI.Sprite(res.p4_black_car.texture);
  // 隐藏'红色赛道汽车'精灵
  trackCar["car4"].visible = false;
  // 设置'红色赛道汽车'精灵位置
  trackCar["car4"].position.set(145, 980);

  // 将两个赛道和三个路障桩和一个奖励金币和四辆汽车等精灵添加到'游戏场景'(赛道、障碍物及汽车)容器中
  p4LaneGroup.addChild(
    p4_lane1,
    p4_lane2,
    trackBarrie["barrier1"],
    trackBarrie["barrier2"],
    trackBarrie["barrier3"],
    trackBarrie["barrier4"],
    trackCar["car1"],
    trackCar["car2"],
    trackCar["car3"],
    trackCar["car4"]
  );

  // 创建'操作区'容器
  let p4ToolGroup = new PIXI.Container();
  // 设置'操作区'容器宽高
  p4ToolGroup.width = 750;
  p4ToolGroup.height = 150;
  // 设置'操作区'容器位置
  p4ToolGroup.position.set(0, app.view.height - p4ToolGroup._height);
  // 绘制'操作区'容器背景
  let p4ToolBg = new PIXI.Graphics();
  // p4ToolBg.beginFill(0xff9500);
  p4ToolBg.beginFill(0xee4512);
  p4ToolBg.drawRect(0, 0, 750, 150);
  p4ToolBg.endFill();

  // 创建'左按钮'精灵
  let p4LeftBtn = new PIXI.Sprite.from(res.p4_left_btn.texture);
  // 设置'左按钮'精灵的位置
  p4LeftBtn.position.set(22, 22);
  // 启用'左按钮'精灵交互响应
  p4LeftBtn.interactive = true;
  // 给'左按钮'精灵绑定触摸事件
  p4LeftBtn.on("tap", goLeft);
  // 汽车向左移动的方法
  function goLeft() {
    // 如果更新后的汽车当前位置不在应急车道上
    if (_randomLane > 0) {
      // 更新汽车x轴位置
      _randomLane -= 1;
    }
    // 如果汽车跑到了应急车道上
    if (_randomLane === 0) {
      // 开启减分模式
      isEmergencyLane = true;
    } else {
      // 如果汽车不在应急车道上,则开启加分模式
      isEmergencyLane = false;
    }
    // 设置激活汽车的位置
    trackCar[`car${global.gameActiveColorCar}`].x =
      p4CarInTrackArr[_randomLane].x;
  }

  // 创建'右按钮'精灵
  let p4RightBtn = new PIXI.Sprite.from(res.p4_right_btn.texture);
  // 设置'右按钮'精灵位置
  p4RightBtn.position.set(488, 22);
  // 启用'右按钮'精灵交互响应
  p4RightBtn.interactive = true;
  // 给'右按钮'精灵绑定触摸事件
  p4RightBtn.on("tap", goRight);
  // 让汽车向右移动的方法
  function goRight() {
    // 如果汽车当前位置小于赛道宽度
    if (_randomLane < p4CarInTrackArr.length - 1) {
      // 更新汽车x轴位置
      _randomLane += 1;
    }
    // 如果汽车跑到了应急车道上
    if (_randomLane === p4CarInTrackArr.length - 1) {
      // 开启减分模式
      isEmergencyLane = true;
    } else {
      // 如果汽车不在应急车道上,则开启加分模式
      isEmergencyLane = false;
    }
    // 设置激活汽车的位置
    trackCar[`car${global.gameActiveColorCar}`].x =
      p4CarInTrackArr[_randomLane].x;
  }

  // 捕获键盘上的上下左右四个箭头键
  let left = keyboard("ArrowLeft"),
    up = keyboard("ArrowUp"),
    right = keyboard("ArrowRight"),
    down = keyboard("ArrowDown");

  // 处理函数,当左箭头键被按下时触发
  left.press = () => {
    // 调用让汽车向左移动的方法
    goLeft();
  };
  // 处理函数,当上箭头键被按下时触发
  up.press = () => {};
  // 处理函数,当右箭头键被按下时触发
  right.press = () => {
    // 调用让汽车向右移动的方法
    goRight();
  };
  // 处理函数,当下箭头键被按下时触发
  down.press = () => {};
  // 将绘制背景和左移按钮和右移按钮添加到'操作区'容器中
  p4ToolGroup.addChild(p4ToolBg, p4LeftBtn, p4RightBtn);

  // 创建'倒计时'容器
  let p4CountdownGroup = new PIXI.Container();
  // 隐藏'倒计时'容器
  p4CountdownGroup.visible = false;
  // 创建'数字外圈'精灵
  let p4_04 = new PIXI.Sprite.from(res.p4_04.texture);
  // 设置'数字外圈'精灵位置
  p4_04.position.set(150, 150);
  // 创建'倒计时文本'精灵
  let p4CountdownText = new PIXI.Text(global.gameCountdown, {
    fontFamily: "zkkl",
    fontSize: 150,
    fill: 0x000000,
    fontWeight: "bold",
  });
  // 设置'倒计时文本'精灵位置
  p4CountdownText.position.set(
    (p4_04.width - p4CountdownText.width) / 2,
    (p4_04.height - p4CountdownText.height) / 2
  );
  // 设置'倒计时'容器位置
  p4CountdownGroup.position.set(
    (app.view.width - p4_04.width) / 2,
    (app.view.height - p4_04.height) / 2
  );
  // 将'数字外圈'精灵和'倒计时'文本精灵添加到'倒计时'容器中
  p4CountdownGroup.addChild(p4_04, p4CountdownText);

  // 将'顶部状态栏背景'精灵和'得分'文本精灵和'得分'文本和'倒计时'容器添加到'顶部状态栏'容器中
  p4TopGroup.addChild(
    p4_01,
    p4TotalScoreText1,
    p4TotalScoreText2,
    p4CountdownGroup
  );
  // 将'顶部状态栏'容器和'游戏场景'(赛道、障碍物及汽车)容器和'操作区'容器添加到'第四页'容器中
  p4.addChild(p4TopGroup, p4LaneGroup, p4ToolGroup);

  // 设置'顶部状态栏'容器和'操作区'容器的层级
  p4TopGroup.zIndex = p4ToolGroup.zIndex = 2;
  // 设置'游戏场景'(赛道、障碍物及汽车)容器的层级
  p4LaneGroup.zIndex = 1;
  // 对容器设置该属性后 zIndex才生效
  p4.sortableChildren = true;
  // 将'第四页'容器添加到舞台中
  app.stage.addChild(p4);

  // 开启加分模式
  let isEmergencyLane = false;
  // 设置四个赛道中的障碍物随机速度
  let barrieRdArr = {
    rd1: randomInt(global.gameLaneSpeed, global.gameBarrieMaxSpeed),
    rd2: randomInt(global.gameLaneSpeed, global.gameBarrieMaxSpeed),
    rd3: randomInt(global.gameLaneSpeed, global.gameBarrieMaxSpeed),
    rd4: randomInt(global.gameLaneSpeed, global.gameBarrieMaxSpeed),
  };
  // 结束游戏的方法
  let gameOver = function () {
    // 停止游戏速度增加(让敌人停止移动)
    clearInterval(_timer2);
    // 更新游戏状态(设置为暂停)
    global.gamePlay = false;
    // //左右按钮不可点击
    // p4RightBtn.interactive = p4LeftBtn.interactive = false;
    // 隐藏'第四页'容器
    p4.visible = false;
    // 显示'第五页'容器
    p5.visible = true;

    // 文案显示
    let resColorCar = "";
    // 根据激活汽车设置对应的文本
    switch (global.gameActiveColorCar) {
      case 1:
        resColorCar = "黄色";
        break;
      case 2:
        resColorCar = "白色";
        break;
      case 3:
        resColorCar = "红色";
        break;
      case 4:
        resColorCar = "黑色";
        break;
    }
    // 更新'最终得分文本1'精灵的内容
    p5Text1.text = `本局游戏中，您用${resColorCar}汽车获得`;
    // resCar["car1"].visible =resCar["car2"].visible =resCar["car3"].visible =resCar["car4"].visible = false;
    // 显示激活汽车的精灵
    resCar[`car${global.gameActiveColorCar}`].visible = true;
    // 更新'最终得分文本2'精灵的内容
    p5Text2.text = global.gameResScore;
    // 设置'最终得分文本2'精灵的位置
    p5Text2.position.set((app.view.width - p5Text2.width) / 2 - 30, 260);
    // 设置'最终得分文本3'精灵的位置
    p5Text3.position.set(
      (app.view.width - p5Text2.width) / 2 - 30 + p5Text2.width,
      260
    );
  };

  // 开启游戏循环

  /**** p4页 end ****/

  /**** p5页 start ****/
  // 创建'第五页'容器
  let p5 = new PIXI.Container();
  // 隐藏'第五页'容器
  p5.visible = false;
  // 设置'第五页'容器的宽高
  p5.width = 750;
  p5.height = 1160;
  // 设置'第五页'容器的位置
  p5.position.set(0, (app.view.height - p5._height) / 2);
  // 创建'第五页标题'文本精灵
  let p5_01 = new PIXI.Sprite.from(res.p5_01.texture);
  // 设置'第五页标题'文本精灵位置
  p5_01.position.set((app.view.width - p5_01.width) / 2, 0);
  // 创建'再来一局按钮'精灵
  let p5_02 = new PIXI.Sprite.from(res.p5_02.texture);
  // 设置'再来一局按钮'精灵的位置
  p5_02.position.set(
    (app.view.width - p5_02.width) / 2,
    p5._height - p5_02.height
  );
  // 开启'再来一局按钮'精灵的交互响应
  p5_02.interactive = true;
  // 给'再来一局按钮'精灵绑定触摸事件
  p5_02.on("tap", () => {
    // 隐藏'第五页'容器
    p5.visible = false;
    // 调用开启游戏的方法
    gameStart();
  });

  // 创建'汽车光辉'精灵
  let p5_03 = new PIXI.Sprite.from(res.p5_03.texture);
  // 设置'汽车光辉'精灵位置
  p5_03.position.set(375, 660);
  // 设置'汽车光辉'精灵旋转的弧度值
  p5_03.rotation = 0;
  // 设置'汽车光辉'精灵的原点
  p5_03.pivot.set(512 / 2, 508 / 2);

  // 创建'最终得分文本1'文本精灵
  let p5Text1 = new PIXI.Text("本局游戏中，您用黄色汽车获得", {
    fontFamily: "zkkl",
    fontSize: 40,
    fill: 0x000000,
  });
  // 设置'最终得分文本1'文本精灵位置
  p5Text1.position.set((app.view.width - p5Text1.width) / 2, 180);
  // 创建'最终得分文本2'文本精灵
  let p5Text2 = new PIXI.Text("0", {
    fontFamily: "zkkl",
    fontSize: 70,
    fill: 0xff1a1a,
    fontWeight: "bold",
    dropShadow: true,
    dropShadowColor: "#cc9732",
    dropShadowBlur: 0,
    dropShadowAngle: Math.PI / 6,
    dropShadowDistance: 6,
  });
  // 设置'最终得分文本2'文本精灵位置
  p5Text2.position.set((app.view.width - p5Text2.width) / 2 - 30, 260);
  // 创建'分字'文本精灵
  let p5Text3 = new PIXI.Text("分", {
    fontFamily: "zkkl",
    fontSize: 70,
    fill: 0x000000,
    fontWeight: "bold",
    dropShadow: true,
    dropShadowColor: "#cc9732",
    dropShadowBlur: 0,
    dropShadowAngle: Math.PI / 6,
    dropShadowDistance: 6,
  });
  // 设置'分字'文本精灵的位置
  p5Text3.position.set(
    (app.view.width - p5Text2.width) / 2 - 30 + p5Text2.width,
    260
  );

  // 得分汽车
  let resCar = {};
  // 创建'黄色得分汽车'精灵
  resCar["car1"] = new PIXI.Sprite.from(res.p5_yellow_car.texture);
  // 设置'黄色得分汽车'精灵
  resCar["car1"].position.set((app.view.width - resCar["car1"].width) / 2, 540);
  // 创建'白色得分汽车'精灵
  resCar["car2"] = new PIXI.Sprite.from(res.p5_white_car.texture);
  // 设置'白色得分汽车'精灵
  resCar["car2"].position.set((app.view.width - resCar["car2"].width) / 2, 540);
  // 创建'红色得分汽车'精灵
  resCar["car3"] = new PIXI.Sprite.from(res.p5_red_car.texture);
  // 设置'红色得分汽车'精灵
  resCar["car3"].position.set((app.view.width - resCar["car3"].width) / 2, 540);
  // 创建'黑色得分汽车'精灵
  resCar["car4"] = new PIXI.Sprite.from(res.p5_black_car.texture);
  // 设置'黑色得分汽车'精灵
  resCar["car4"].position.set((app.view.width - resCar["car4"].width) / 2, 540);

  // 隐藏得分汽车
  resCar["car1"].visible =
    resCar["car2"].visible =
    resCar["car3"].visible =
    resCar["car4"].visible =
      false;

  // 将'第五页标题'、'再来一局按钮'、'汽车光辉'、'最终得分文本1'、'最终得分文本2'、'最终得分文本3'、四个汽车精灵添加到'第五页'容器
  p5.addChild(
    p5_01,
    p5_02,
    p5_03,
    p5Text1,
    p5Text2,
    p5Text3,
    resCar["car1"],
    resCar["car2"],
    resCar["car3"],
    resCar["car4"]
  );
  // 将‘容器添加舞台中
  app.stage.addChild(p5);
  /**** p5页 end ****/

  // 开启游戏循环
  app.ticker.add((delta) => gameLoop(delta));

  // 处理函数,当开始游戏循环时触发
  function gameLoop(delta) {
    // 如果游戏状态为开启状态
    if (global.gamePlay) {
      // 让两个赛道精灵动起来
      p4_lane1.y = p4_lane1.y + global.gameLaneSpeed + _plusSpeed;
      p4_lane2.y = p4_lane2.y + global.gameLaneSpeed + _plusSpeed;

      // 如果第一个赛道精灵的向下移动了自身的长度
      if (p4_lane1.y >= p4_lane1.height) {
        // 更新第一个赛道精灵的位置
        p4_lane1.y = 0;
      }
      // 如果第二个赛道精灵向下移动到了自身的长度
      if (p4_lane2.y >= 0) {
        // 更新第二个赛道精灵的位置
        p4_lane2.y = -p4_lane1.height;
      }

      // 通过得分模式更新当前用户的总得分
      if (isEmergencyLane) {
        // 如果是减分模式
        global.gameResScore -= 1;
      } else {
        // 如果是加分模式
        global.gameResScore += 1;
      }

      if (global.gameResScore < 0) {
        global.gameResScore = 0;
      }
      // 将用户当前得分赋值给'得分'文本精灵
      p4TotalScoreText2.text = global.gameResScore;
      // 更新'黄色路障桩'精灵的位置
      trackBarrie["barrier1"].y =
        trackBarrie["barrier1"].y + barrieRdArr.rd1 + _plusSpeed;
      // 更新'蓝色路障桩'精灵的位置
      trackBarrie["barrier2"].y =
        trackBarrie["barrier2"].y + barrieRdArr.rd2 + _plusSpeed;
      // 更新'红色路障桩'精灵的位置
      trackBarrie["barrier3"].y =
        trackBarrie["barrier3"].y + barrieRdArr.rd3 + _plusSpeed;
      // 更新'奖励金币'精灵的位置
      trackBarrie["barrier4"].y =
        trackBarrie["barrier4"].y + barrieRdArr.rd4 + _plusSpeed;
      // 如果'黄色路障桩'精灵的移动距离超出边界
      if (trackBarrie["barrier1"].y >= 1200) {
        // 拿到一个随机数
        let rdNum = randomInt(0, 4);
        // 更新'黄色路障桩'精灵的位置(随机)
        trackBarrie["barrier1"].position.set(
          p4BarrieInTrackArr[rdNum].x,
          p4BarrieInTrackArr[rdNum].y
        );
        // 更新'黄色路障桩'精灵的速度(随机)
        barrieRdArr.rd1 = randomInt(
          global.gameLaneSpeed,
          global.gameBarrieMaxSpeed
        );
      }
      // 如果'蓝色路障桩'精灵的移动距离超出边界
      if (trackBarrie["barrier2"].y >= 1200) {
        // 拿到一个随机数
        let rdNum = randomInt(0, 4);
        // 更新'蓝色路障桩'精灵的位置(随机)
        trackBarrie["barrier2"].position.set(
          p4BarrieInTrackArr[rdNum].x,
          p4BarrieInTrackArr[rdNum].y
        );
        // 更新'蓝色路障桩'精灵的速度(随机)
        barrieRdArr.rd2 = randomInt(
          global.gameLaneSpeed,
          global.gameBarrieMaxSpeed
        );
      }
      // 如果'红色路障桩'精灵的移动距离超出边界
      if (trackBarrie["barrier3"].y >= 1200) {
        // 拿到一个随机数
        let rdNum = randomInt(0, 4);
        // 更新'红色路障桩'精灵的位置(随机)
        trackBarrie["barrier3"].position.set(
          p4BarrieInTrackArr[rdNum].x,
          p4BarrieInTrackArr[rdNum].y
        );
        // 更新'红色路障桩'精灵的速度(随机)
        barrieRdArr.rd3 = randomInt(
          global.gameLaneSpeed,
          global.gameBarrieMaxSpeed
        );
      }
      // 如果'奖励金币'精灵的移动距离超出边界
      if (trackBarrie["barrier4"].y >= 1200) {
        // 拿到一个随机数
        let rdNum = randomInt(0, 4);
        // 更新'奖励金币'精灵的位置(随机)
        trackBarrie["barrier4"].position.set(
          p4BarrieInTrackArr[rdNum].x,
          p4BarrieInTrackArr[rdNum].y
        );
        // 更新'奖励金币'精灵的速度(随机)
        barrieRdArr.rd4 = randomInt(
          global.gameLaneSpeed,
          global.gameBarrieMaxSpeed
        );
        // 显示'奖励金币'精灵
        trackBarrie["barrier4"].visible = true;
      }

      // 检查当前用户的汽车与'黄色路障桩'精灵是否碰撞
      let carBarrier1 = bump.hit(
        trackCar[`car${global.gameActiveColorCar}`],
        trackBarrie["barrier1"],
        true
      );
      // 检查当前用户的汽车与'蓝色路障桩'精灵是否碰撞
      let carBarrier2 = bump.hit(
        trackCar[`car${global.gameActiveColorCar}`],
        trackBarrie["barrier2"],
        true
      );
      // 检查当前用户的汽车与'红色路障桩'精灵是否碰撞
      let carBarrier3 = bump.hit(
        trackCar[`car${global.gameActiveColorCar}`],
        trackBarrie["barrier3"],
        true
      );
      // 检查当前用户的汽车与'奖励金币'精灵是否碰撞
      let carBarrier4 = bump.hit(
        trackCar[`car${global.gameActiveColorCar}`],
        trackBarrie["barrier4"]
      );
      // 如果当前用户的汽车与路障桩精灵有碰撞
      if (carBarrier1 || carBarrier2 || carBarrier3) {
        // 调用结束游戏的方法
        gameOver();
      } else if (carBarrier4) {
        // 如果当前用户的汽车与奖励金币精灵有碰撞,则隐藏碰撞的奖励金币精灵
        trackBarrie["barrier4"].visible = false;
        // 更新当前用户得分分数
        global.gameResScore += global.gameScoreBonus;
      }
    }
    // 更新'数字外圈'精灵的弧度值
    p4_04.rotation -= 1;
    // 更新'汽车光辉'精灵的弧度值
    p5_03.rotation += 0.05;
  }
}
